package net.dreamlu.demo.xss;

import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import net.dreamlu.demo.form.UserForm;
import net.dreamlu.mica.core.result.R;
import net.dreamlu.mica.core.result.SystemCode;
import net.dreamlu.mica.xss.core.XssCleanIgnore;
import net.dreamlu.mica.xss.core.XssException;
import org.springframework.core.NestedExceptionUtils;
import org.springframework.http.HttpStatus;
import org.springframework.http.converter.HttpMessageConversionException;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import jakarta.validation.constraints.NotEmpty;
import org.springframework.web.method.annotation.MethodArgumentConversionNotSupportedException;

/**
 * mica-xss 演示
 *
 * @author L.cm
 */
@Slf4j
@Validated
@RestController
@Tag(name = "模块::xss示例")
@RequestMapping("xss")
public class XssController {

	/**
	 * 示例，处理校验模式的异常 json
	 */
	@ExceptionHandler(HttpMessageNotReadableException.class)
	@ResponseStatus(HttpStatus.BAD_REQUEST)
	public R<Object> handleError(HttpMessageNotReadableException e) {
		log.error("消息不能读取:{}", e.getMessage());
		Throwable rootCause = NestedExceptionUtils.getRootCause(e);
		if (rootCause instanceof XssException xssException) {
			// xss 的异常
			return R.fail("参数：%s 值：%s 存在 xss 注入".formatted(xssException.getName(), xssException.getInput()));
		}
		return R.fail(SystemCode.MSG_NOT_READABLE);
	}

	/**
	 * 示例，处理校验模式的异常 form
	 */
	@ExceptionHandler(MethodArgumentConversionNotSupportedException.class)
	@ResponseStatus(HttpStatus.BAD_REQUEST)
	public R<Object> handleError(MethodArgumentConversionNotSupportedException e) {
		log.error("消息不能读取,转换异常:{}", e.getMessage());
		Throwable rootCause = NestedExceptionUtils.getRootCause(e);
		if (rootCause instanceof XssException xssException) {
			// xss 的异常
			return R.fail("请求参数值：%s 存在 xss 注入".formatted(xssException.getInput()));
		}
		return R.fail(SystemCode.MSG_NOT_READABLE);
	}

	@GetMapping("form")
	public R<String> form(@NotEmpty String name) {
		return R.success(name);
	}

	@PostMapping("body")
	@XssCleanIgnore
	public R<UserForm> body(@RequestBody @Validated UserForm form) {
		return R.success(form);
	}

}
